1 /*
2 Copyright: Marcelo S. N. Mancini (Hipreme|MrcSnm), 2018 - 2021
3 License:   [https://creativecommons.org/licenses/by/4.0/|CC BY-4.0 License].
4 Authors: Marcelo S. N. Mancini
5 
6 	Copyright Marcelo S. N. Mancini 2018 - 2021.
7 Distributed under the CC BY-4.0 License.
8    (See accompanying file LICENSE.txt or copy at
9 	https://creativecommons.org/licenses/by/4.0/
10 */
11 module hip.api.renderer.var_packing;
12 import hip.api.renderer.shadervar;
13 
14 pragma(LDC_no_typeinfo)
15 struct VarPosition
16 {
17     size_t startPos;
18     size_t endPos;
19     size_t size;
20 }
21 
22 /**
23 *   Uses the OpenGL's GLSL Std 140 for getting the variable position.
24 *   This function must return what is the end position given the last variable size.
25 */
26 VarPosition glSTD140(ref ShaderVar* v, size_t lastAlignment = 0, bool isLast = false)
27 {
28     size_t size = v.varSize;
29 
30     if(lastAlignment == 0)
31         return VarPosition(0,size,size);
32 
33     size_t size4 = size*4;
34 
35     //((8 % 16) > (8+8) % 16  || 8 % 16 == 0) && (8+8 % 16 != 0)
36     // 8 + (8 % 16) + 8
37 
38     if((lastAlignment % size4 > (lastAlignment+size) % size4 || size % size4 == 0) && (lastAlignment+size) % size4 != 0)
39     {
40         size_t startPos = lastAlignment;
41         if(startPos % size4 != 0) startPos = startPos + (size4 - (startPos % size4));
42 
43         return VarPosition(startPos, startPos+size, size);
44     }
45 
46     return VarPosition(lastAlignment, lastAlignment + size, size);
47 }
48 
49 /**
50 *   Uses the OpenGL's GLSL Std 140 for getting the variable position.
51 *   This function must return what is the end position given the last variable size.
52 */
53 VarPosition dxHLSL4(ref ShaderVar* v, size_t lastAlignment = 0, bool isLast = false)
54 {
55     size_t newN = v.varSize;
56     if(isLast)
57     {
58         size_t startPos = lastAlignment;
59         if(startPos % 16 != 0) startPos = startPos + (16 - (startPos % 16));
60         size_t endPos = startPos+newN;
61         if(endPos % 16 != 0) endPos = endPos + (16 - (endPos % 16));
62         return VarPosition(startPos, endPos, newN);
63     }
64     if(lastAlignment == 0)
65         return VarPosition(0,newN,newN);
66 
67 
68     size_t n4 = newN*4;
69 
70     //((8 % 16) > (8+8) % 16  || 8 % 16 == 0) && (8+8 % 16 != 0)
71     // 8 + (8 % 16) + 8
72     
73     if((lastAlignment % n4 > (lastAlignment+newN) % n4 || newN % n4 == 0) && (lastAlignment+newN) % n4 != 0)
74     {
75         size_t startPos = lastAlignment+ (lastAlignment % n4);
76         return VarPosition(startPos, startPos+newN, newN);
77     }
78     
79     return VarPosition(lastAlignment, lastAlignment + newN, newN);
80 }
81 
82 VarPosition nonePack(ref ShaderVar* v, size_t lastAlignment = 0, bool isLast = false)
83 {
84     return VarPosition(0,0,0);
85 }